// UDKDevKitVSXDebuggerInterface.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <gcroot.h>
#include "CommandInterface.h"

/*
http://udn.epicgames.com/Three/udkConduitInterface.html

Here is list of commands:

addbreakpoint

<classname>  <linenumber>

removebreakpoint
<classname>  <linenumber>

These commands are used to tell UE3 to add/remove breakpoints. is the name of the call where the breakpoint will exists and is the line number.
addwatch

<varname>

removewatch
<varname>

These commands tell UE3 to add/remove user defined watches. You should fully describe it (for example: pawn.playerreplicationinfo.playername).
clearwatch
This command takes no parameters and will clear all user watches.

changestack

<stackid>

This command causes the engine to jump to a given position in the callstack.
setdatawatch

<watchtext>

This command sets a breakpoint on data access of a given variable.
breakonnone

<0=false|1=true>

Use the breakonnone command to instruct the debugger to break whenever an access none error occurs.
break
Tells UE3 to break as soon as possible.

stopdebugging
This command shuts down the debugger and stop the debugging session.

go
stepinto
stepover
stepoutof
These commands control the execution of the debugger.
*/

gcroot<UDKDevKitVSX::Interfaces::IUdkConduit ^> udkConduitInterface;

extern "C"
{
	typedef void (*CallbackPointer)(const char*);
	CallbackPointer callbackPointer = nullptr;
	bool notfirst = false;

	UDKDevKitVSX::Interfaces::IUdkConduit ^ GetUdkConduitInterface()
	{
		auto varUdkConduitInterface = (UDKDevKitVSX::Interfaces::IUdkConduit ^) udkConduitInterface;
		if (varUdkConduitInterface == nullptr)
		{
			udkConduitInterface = UDKDevKitVSX::UdkConduit::Create(gcnew CCommandInterface(callbackPointer));
		}

		return udkConduitInterface;
	}

	__declspec(dllexport) void SetCallback(void* callbackFunc)
	{
		callbackPointer = (CallbackPointer) callbackFunc;
	}

	__declspec(dllexport) void ShowDllForm() 
	{
		GetUdkConduitInterface()->ShowDllForm();
	}

	__declspec(dllexport) void BuildHierarchy()
	{
		GetUdkConduitInterface()->BuildHierarchy();
	}

	__declspec(dllexport) void ClearHierarchy()
	{
		GetUdkConduitInterface()->ClearHierarchy();
	}

	__declspec(dllexport) void AddClassToHierarchy(const char* className)
	{
		GetUdkConduitInterface()->AddClassToHierarchy(gcnew System::String(className));
	}

	__declspec(dllexport) void ClearWatch(int watchType)
	{
		GetUdkConduitInterface()->ClearWatch(watchType);
	}

	__declspec(dllexport) void ClearAWatch(int watchType)
	{
		GetUdkConduitInterface()->ClearAWatch(watchType);
	}

	__declspec(dllexport) int AddAWatch(int watchType, int parentIndex, const char* varName, const char* varValue)
	{
		return GetUdkConduitInterface()->AddAWatch(watchType, parentIndex, gcnew System::String(varName), gcnew System::String(varValue));
	}

	__declspec(dllexport) void LockList(int watchList)
	{
		GetUdkConduitInterface()->LockList(watchList);
	}

	__declspec(dllexport) void UnlockList(int watchList)
	{
		GetUdkConduitInterface()->UnlockList(watchList);
	}

	__declspec(dllexport) void AddBreakpoint(const char* className, int lineNo)
	{
		GetUdkConduitInterface()->AddBreakpoint(gcnew System::String(className), lineNo);
	}

	__declspec(dllexport) void RemoveBreakpoint(const char* className, int lineNo)
	{
		GetUdkConduitInterface()->RemoveBreakpoint(gcnew System::String(className), lineNo);
	}

	__declspec(dllexport) void EditorLoadClass(const char* className)
	{
		GetUdkConduitInterface()->EditorLoadClass(gcnew System::String(className));
	}

	__declspec(dllexport) void EditorGotoLine(int lineNo, int highlight)
	{
		GetUdkConduitInterface()->EditorGotoLine(lineNo, highlight);
	}

	__declspec(dllexport) void AddLineToLog(const char* text)
	{
		GetUdkConduitInterface()->AddLineToLog(gcnew System::String(text));
	}

	__declspec(dllexport) void CallStackClear()
	{
		GetUdkConduitInterface()->CallStackClear();
	}

	__declspec(dllexport) void CallStackAdd(const char* callStackEntry)
	{
		GetUdkConduitInterface()->CallStackAdd(gcnew System::String(callStackEntry));
	}

	__declspec(dllexport) void SetCurrentObjectName(const char* objectName)
	{
		GetUdkConduitInterface()->SetCurrentObjectName(gcnew System::String(objectName));
	}

	__declspec(dllexport) void DebugWindowState(int stateCode)
	{
		GetUdkConduitInterface()->DebugWindowState(stateCode);
	}
}
